package com.heima.comment.service.impl;

import com.heima.apis.user.IUserClient;
import com.heima.apis.wemedia.IWemediaClient;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.pojos.ApCommentRepay;
import com.heima.comment.pojos.CommentRepayVo;
import com.heima.comment.service.CommentRepayService;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.utils.thread.AppThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CommentRepayServiceImpl implements CommentRepayService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IWemediaClient wemediaClient;

    @Autowired
    private IUserClient userClient;

    @Override
    public ResponseResult insert(CommentRepaySaveDto dto) {
        //1.1参数校验
        if(dto == null || dto.getCommentId() == null)
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);

        if(dto.getContent() == null)
            return ResponseResult.errorResult(501, "评论内容不能为空");

        //1.2登录校验
        Integer userId = AppThreadLocalUtil.getUserID();
        if (userId == null || userId == 0)
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);


        //2.1评论回复内容长度校验
        if(dto.getContent().length() > 100)
            return ResponseResult.errorResult(501, "评论不能超过140字");
        //2.2评论回复内容文本垃圾检测
        if(!wemediaClient.scanText(dto.getContent()))
            return ResponseResult.errorResult(501, "评论存在违规内容");
        //3.1将评论回复存入表中
        Query query = Query.query(Criteria.where("_id").is(dto.getCommentId()));
        ApComment apComment = mongoTemplate.findOne(query, ApComment.class, "ap_comment");
        if(apComment == null)
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);

        //文章作者id,作者名称与评论表保持一致
        ApCommentRepay apCommentRepay = ApCommentRepay.builder()
                        .authorId(userId)
                        .authorName(userClient.getName(userId))
                        .commentId(dto.getCommentId())
                        .content(dto.getContent())
                        .likes(0)
                        .createdTime(new Date())
                        .updatedTime(new Date())
                        .build();

        mongoTemplate.insert(apCommentRepay);
        //3.2更新评论表评回复数
        Update update = Update.update("reply", apComment.getReply() + 1);
        mongoTemplate.updateFirst(query,update, "ap_comment");

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult like(CommentRepayLikeDto dto) {
        //1.1参数校验
        if(dto == null || dto.getCommentRepayId() == null || dto.getOperation() == null)
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        //1.2登录校验
        Integer userId = AppThreadLocalUtil.getUserID();
        if (userId == null || userId == 0)
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);

        //查询要操作的评论回复
        Query query = Query.query(Criteria.where("_id").is(dto.getCommentRepayId()));
        ApCommentRepay apCommentRepay = mongoTemplate.findOne(query, ApCommentRepay.class);
        //2.1如果点赞修改评论回复表中点赞量+1,评论点赞表中新增点赞信息
        if(dto.getOperation() == 0) {
            Update update = Update.update("likes", apCommentRepay.getLikes() + 1);
            mongoTemplate.updateFirst(query, update, "ap_comment_repay");
            ApCommentLike apCommentLike = ApCommentLike.builder()
                    .authorId(userId)
                    .commentId(dto.getCommentRepayId())
                    .operation(dto.getOperation())
                    .build();
            mongoTemplate.insert(apCommentLike, "ap_comment_like");
            //2.2如果取消点赞修改评论回复表中点赞量-1,并删除点赞表中信息
        }else {
            Update update = Update.update("likes", apCommentRepay.getLikes() - 1);
            mongoTemplate.updateFirst(query, update, "ap_comment_repay");

            mongoTemplate.remove(Query.query(Criteria.where("authorId").is(userId).and("commentId").is(dto.getCommentRepayId())), "ap_comment_like");
        }
        Map<String, Integer> map = new HashMap<>();
        map.put("likes", mongoTemplate.findOne(query, ApCommentRepay.class).getLikes());
        return ResponseResult.okResult(map);
    }

    @Override
    public ResponseResult load(CommentRepayDto dto) {
        //1参数校验
        if(dto == null || dto.getCommentId() == null || dto.getMinDate() == null)
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        dto.checkParam();
        //2查询评论回复表中当前评论下的评论(分页,大于最小创建时间,倒序)
        Query query = Query.query(Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate()))
                .with(Sort.by(Sort.Order.desc("createdTime")))
                .limit(dto.getSize());
        List<ApCommentRepay> apCommentRepayList = mongoTemplate.find(query, ApCommentRepay.class);
        //点赞显示,游客不显示,用户点赞回显
        Integer userId = AppThreadLocalUtil.getUserID();
        if (userId == null)
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        //游客
        if (userId == 0)
            return ResponseResult.okResult(apCommentRepayList);
        //用户
        //根据用户id查询该用户点赞的所有评论
        List<CommentRepayVo> commentRepayVoList = apCommentRepayList.stream().map(apCommentRepay -> {
            CommentRepayVo commentRepayVo = new CommentRepayVo();
            BeanUtils.copyProperties(apCommentRepay, commentRepayVo);
            ApCommentLike apCommentLike = mongoTemplate.findOne(Query.query(Criteria.where("authorId").is(userId).and("commentId").is(apCommentRepay.getId())), ApCommentLike.class);
            commentRepayVo.setOperation(apCommentLike == null ? (short) 1 : (short) 0);
            return commentRepayVo;
        }).collect(Collectors.toList());

        return ResponseResult.okResult(commentRepayVoList);
    }
}
